
#include <stdint.h>
#include <assert.h>
#include <phApp_Init.h>
#include <phNfcLib_Int.h>
#include <phNfcLib_Initialization.h>
#include "config/config3.h"
#include "Reader.h"

#pragma pack(push, 1)

typedef struct {
    uint8_t vasup_a;
    uint8_t format;
    uint8_t terminal_info; // Bit 7: VAS supported, Bit 6: User authentication required, Lower nibble: Terminal type length
    uint8_t terminal_type;      //Terminal type and sub-type values to be defined in a separate configuration document。
    uint8_t terminam_sub_type;    
    uint8_t terminal_type_data[16]; //TCI data, variable length based on terminal_info
} apple_epc2_pack_t;

#pragma pack(pop)

typedef struct {
    uint8_t length;
    union {
        apple_epc2_pack_t pack;
        uint8_t raw[32]; // Raw data buffer for the frame
    } payload;
}apple_epc2_frame_t;

static const uint8_t hid_apple_epc2_frame[8] = {
    0x6A, 0x02, 0xC3, 0x02, 0x02, 0x02, 0x09, 0x01,
};

//6a  02  c3  02  02  02  09  01 

static apple_epc2_frame_t apple_epc2_frame = {
    .length = 8,
    .payload.raw = {0x6A, 0x02, 0xC3, 0x02, 0x02, 0x02, 0x09, 0x01}, // Initial command frame
};

// Bitmask definitions for terminal info field
#define APPLE_EPC2_VAS_NOT_SUPPORTED_MASK       (0x01U << 7)
#define APPLE_EPC2_USER_AUTH_NOT_REQUIRED_MASK  (0x01U << 6)
#define APPLE_EPC2_TERMINAL_TYPE_LEN_MASK   (0x0FU)

/**
 * @brief 构建终端信息字段
 *
 * 组装一个8位字段，包含以下信息：
 * - bit7: VAS是否支持
 * - bit6: 是否需要用户认证
 * - bit3-0: 终端类型长度（必须 <= 15）
 */
static uint8_t apple_epc2_build_terminal_info(uint8_t vas_not_supported, uint8_t user_auth_not_required, uint8_t terminalTypeLength)
{
    uint8_t terminal_info = 0;

    // 确保 terminalTypeLength 不会超出允许范围
    assert(terminalTypeLength <= APPLE_EPC2_TERMINAL_TYPE_LEN_MASK);

    if (vas_not_supported) {
        terminal_info |= APPLE_EPC2_VAS_NOT_SUPPORTED_MASK;
    }

    if (user_auth_not_required) {
        terminal_info |= APPLE_EPC2_USER_AUTH_NOT_REQUIRED_MASK;
    }

    terminal_info |= (terminalTypeLength & APPLE_EPC2_TERMINAL_TYPE_LEN_MASK);

    return terminal_info;
}

/*
    设置EPC2参数
*/

int apple_epc2_set_tci(uint8_t tci[], uint8_t tci_length)
{
    if (tci_length > 16) {
        return -1; // 错误：TCI数据长度超过16字节
    }

    apple_epc2_pack_t* pack = &apple_epc2_frame.payload.pack;
    // 设置终端信息字段
    pack->terminal_info = apple_epc2_build_terminal_info(1, 1, tci_length);

    // 拷贝TCI数据到帧中
    for (uint8_t i = 0; i < tci_length; i++) {
        pack->terminal_type_data[i] = tci[i];
    }

    // 更新帧长度
    apple_epc2_frame.length = 5 + tci_length;

    return 0; // 成功
}

/*设置终端类型*/
void apple_epc2_set_terminal_type(uint8_t type, uint8_t sub_type)
{
    apple_epc2_pack_t* pack = &apple_epc2_frame.payload.pack;
    pack->terminal_type = type;
    pack->terminam_sub_type = sub_type;
}


int apple_epc2_a(apple_epc2_frame_t* frame)
{
    phStatus_t  PH_MEMLOC_REM status;
    phStatus_t  PH_MEMLOC_REM statusTmp;
    uint8_t *   PH_MEMLOC_REM pResp = NULL;
    uint16_t    PH_MEMLOC_REM wRespLength = 0;
	phpalI14443p3a_Sw_DataParams_t * pDataParams = &gphNfcLib_Params.spalI14443p3a;
	
	(void)phhalHw_SetConfig(pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TXWAIT_US, 500);
    /* Set halt timeout */
    PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig(
        pDataParams->pHalDataParams,
        PHHAL_HW_CONFIG_TIMEOUT_VALUE_US,
        1000));

    PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig(pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TXCRC, PH_ON));
    PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig(pDataParams->pHalDataParams, PHHAL_HW_CONFIG_RXCRC, PH_ON));
	
    status = phhalHw_Exchange(pDataParams->pHalDataParams, PH_EXCHANGE_DEFAULT, frame->payload.raw, frame->length, &pResp, &wRespLength);

    switch (status & PH_ERR_MASK)
    {
        /* HltA command should timeout -> success */
    case PH_ERR_IO_TIMEOUT:
        return PH_ERR_SUCCESS;
        /* Return protocol error */
    case PH_ERR_SUCCESS:
        return PH_ERR_SUCCESS;
        /* Return other errors */
    default:
        return status;
    }
}


int apple_epc2_a_poll(void){
    uint32_t flag = reader.hfFlags;
    const config_param_t* param = &config_param;
    if(flag & TAG_MASK_SWIFTLANE){
        apple_epc2_frame.payload.raw[0] = 0x6A;
        memcpy(apple_epc2_frame.payload.raw+1, param->swiftlane.epc, 7);
    }
    else
    if(flag & TAG_MASK_WAVELYNX){
        apple_epc2_frame.payload.raw[0] = 0x6A;
        memcpy(apple_epc2_frame.payload.raw+1, param->apple_wallet.epc, 7);
    }
    else if(flag & TAG_MASK_ACCESS_GRID){
        apple_epc2_frame.payload.raw[0] = 0x6A;
        memcpy(apple_epc2_frame.payload.raw+1, param->access_grid.epc, 7);
    }
    else{
        // memcpy(apple_epc2_frame.payload.raw, hid_apple_epc2_frame, 8);
        return -1;
    }

    return apple_epc2_a(&apple_epc2_frame);
}